/**
 * 
 */
package gsoc.ogsadai.model.rcp.diagram.custom.actions;



import gsoc.ogsadai.client.ServerClient;
import gsoc.ogsadai.model.rcp.diagram.edit.parts.WorkflowTypeEditPart;
import gsoc.ogsadai.model.rcp.diagram.part.ValidateAction;
import gsoc.ogsadai.model.rcp.diagram.providers.RequestValidationProvider;
import gsoc.ogsadai.model.properties.PropertiesStyle;
import gsoc.ogsadai.model.util.ModelResourceImpl;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.emf.common.util.Diagnostic;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.util.Diagnostician;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.emf.edit.domain.EditingDomain;
import org.eclipse.emf.validation.marker.MarkerUtil;
import org.eclipse.emf.validation.model.EvaluationMode;
import org.eclipse.emf.validation.model.IConstraintStatus;
import org.eclipse.emf.validation.service.IBatchValidator;
import org.eclipse.emf.validation.service.ModelValidationService;
import org.eclipse.gmf.runtime.common.ui.util.IWorkbenchPartDescriptor;
import org.eclipse.gmf.runtime.common.ui.util.WorkbenchPartDescriptor;
import org.eclipse.gmf.runtime.diagram.ui.parts.IDiagramEditDomain;
import org.eclipse.gmf.runtime.emf.core.util.EMFCoreUtil;
import org.eclipse.gmf.runtime.notation.View;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IObjectActionDelegate;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.dialogs.ListDialog;
import org.eclipse.ui.part.MultiPageEditorPart;

//import gsoc.ogsadai.validator.general.actions.MyValidateActionDelegate;
//import gsoc.ogsadai.validator.general.constraintss.ValidationDelegateClientSelector;

import uk.org.ogsadai.client.toolkit.RequestResource;

/**
 * @author Nicola Salvo
 * 9 Jul 2008
 */
public class DeployWorkflowAction implements IObjectActionDelegate {

	private WorkflowTypeEditPart mySelectedElement;
	 private Text text;
	 private IWorkbenchPart editor;
	 
	public static final String ID = "gsoc.ogsadai.diagram.popup.deployWorkflowID";
	/* (non-Javadoc)
	 * @see org.eclipse.ui.IObjectActionDelegate#setActivePart(org.eclipse.jface.action.IAction, org.eclipse.ui.IWorkbenchPart)
	 */
	public void setActivePart(IAction action, IWorkbenchPart targetPart) {
		editor = targetPart;
	}
	
	public void createPartControl(Composite parent) {
		  text = new Text(parent, SWT.READ_ONLY | SWT.MULTI);
		  OutputStream out = new OutputStream() {
		   @Override
		   public void write(int b) throws IOException {
		    if (text.isDisposed()) return;
		    text.append(String.valueOf((char) b));
		   }
		  };
		  final PrintStream oldOut = System.out;
		  System.setOut(new PrintStream(out));
		  text.addDisposeListener(new DisposeListener() {
		   public void widgetDisposed(DisposeEvent e) {
		    System.setOut(oldOut);
		   }
		  });
		 }

	
	/* (non-Javadoc)
	 * @see org.eclipse.ui.IActionDelegate#run(org.eclipse.jface.action.IAction)
	 */
	/* (non-Javadoc)
	 * @see org.eclipse.ui.IActionDelegate#run(org.eclipse.jface.action.IAction)
	 */
	public void run(IAction action) {
		
		ResourceSet resourceSet = mySelectedElement.getEditingDomain().getResourceSet();// getEditingDomain().getResourceSet();
		View view = (View)mySelectedElement.getModel();
		List styleList = view.getStyles();
		PropertiesStyle style = null;
		
		String serverURL = "";
		String fileName = "/tmp/default.xml";
		//ValidationDelegateClientSelector.running = true;

		
		Shell shell = editor.getSite().getShell();
//		IBatchValidator validator = (IBatchValidator)ModelValidationService.getInstance()
//			.newValidator(EvaluationMode.BATCH);
//		validator.setIncludeLiveConstraints(true);
//		
//		final IStatus status = validator.validate(view.getElement());				
//
//		System.out.println("Validating " + view.getElement());
//		
//		ValidationDelegateClientSelector.running = false;
//
//		Diagnostic diagnostic =new Diagnostician() {
//
//			public String getObjectLabel(EObject eObject) {
//				return EMFCoreUtil.getQualifiedName(eObject, true);
//			}
//		}.validate(view.getElement());
//	
//					
//
//		if (status.isOK()) {
//			MessageDialog.openInformation(shell, "COOL",
//					"validation successful");
//			return;
//		} else {
//			ListDialog dialog = new ListDialog(shell);
//			dialog.setInput(status);
//			dialog.setTitle("BOOO");
//			dialog.setContentProvider(new IStructuredContentProvider() {
//				public void dispose() {
//					// nothing to dispose
//				}
//
//				public Object[] getElements(Object inputElement) {
//					if (status != null && status.isMultiStatus()
//							&& status == inputElement) {
//						return status.getChildren();
//					} else if (status != null && status == inputElement) {
//						return new Object[] { status };
//					}
//					return new Object[0];
//				}
//
//				public void inputChanged(Viewer viewer, Object oldInput,
//						Object newInput) {
//					// Do nothing.
//				}
//			});
//			dialog.setLabelProvider(new LabelProvider() {
//				public String getText(Object element) {
//					if (element instanceof IStatus) {
//						return ((IStatus) element).getMessage();
//					}
//					return null;
//				}
//			});
//			dialog.setBlockOnOpen(true);
//			dialog.setMessage("Errors during validation");
//
//			if (ListDialog.OK == dialog.open()) {
//				Set<EObject> errorSelections = new HashSet<EObject>();
//				if (!status.isMultiStatus()) {
//					IConstraintStatus cstatus = (IConstraintStatus) status;
//					errorSelections.add(cstatus.getTarget());
//				} else {
//					IStatus[] children = status.getChildren();
//					for (int i = 0; i < children.length; i++) {
//						IConstraintStatus cstatus = (IConstraintStatus) children[i];
//						errorSelections.add(cstatus.getTarget());
//					}
//				}
//				//editorPart. .setSelectionToViewer(errorSelections);
//			}
//		}
//
//
//		// Create problem markers on the resources with validation
//		// failures/warnings.
//		try {
//			MarkerUtil.createMarkers(status);
//		} catch (CoreException e) {
//			Activator.getDefault().getLog().log(e.getStatus());
//		}
		
		
		
		
		final IStatus status = ValidateAction.runValidation(mySelectedElement.getDiagramView());
		if (status.isOK()) {
			MessageDialog.openInformation(shell, "COOL",
					"validation successful");
			
		}  else {
			ListDialog dialog = new ListDialog(shell);
			dialog.setInput(status);
			dialog.setTitle("Error");
			dialog.setContentProvider(new IStructuredContentProvider() {
				public void dispose() {
					// nothing to dispose
				}

				public Object[] getElements(Object inputElement) {
					if (status != null && status.isMultiStatus()
							&& status == inputElement) {
						return status.getChildren();
					} else if (status != null && status == inputElement) {
						return new Object[] { status };
					}
					return new Object[0];
				}

				public void inputChanged(Viewer viewer, Object oldInput,
						Object newInput) {
					// Do nothing.
				}
			});
			dialog.setLabelProvider(new LabelProvider() {
				public String getText(Object element) {
					if (element instanceof IStatus) {
						return ((IStatus) element).getMessage();
					}
					return null;
				}
			});
			dialog.setBlockOnOpen(true);
			dialog.setMessage("Errors during validation");

			if (ListDialog.OK == dialog.open()) {
				Set<EObject> errorSelections = new HashSet<EObject>();
				if (!status.isMultiStatus()) {
					IConstraintStatus cstatus = (IConstraintStatus) status;
					errorSelections.add(cstatus.getTarget());
				} else {
					IStatus[] children = status.getChildren();
					for (int i = 0; i < children.length; i++) {
						IConstraintStatus cstatus = (IConstraintStatus) children[i];
						errorSelections.add(cstatus.getTarget());
					}
				}
				//editorPart. .setSelectionToViewer(errorSelections);
			}
			return;
		}
		for (Object obj : styleList) {
			if (obj instanceof PropertiesStyle)				
				style = (PropertiesStyle) obj;			
		}
		if(style != null){
			fileName = "/tmp/"+EcoreUtil.getURI((EObject)style).fragment()+".xml";			
			serverURL = style.getServerURL();			
		}
		try {
			
			FileOutputStream fos = new FileOutputStream(new File(fileName));
			for(Resource resource: resourceSet.getResources()){		
				if(resource instanceof ModelResourceImpl)		
					resource.save(fos,null);
			}
			
			ServerClient server= new ServerClient(serverURL);			
			RequestResource request =  server.executeRequest(fileName);
			Activator.getDefault().getRequestResourceList().add(request);	
			 // getSite().getPage().showView(DataView.ID_VIEW);
		    
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
						

		
	}

	/* (non-Javadoc)
	 * @see org.eclipse.ui.IActionDelegate#selectionChanged(org.eclipse.jface.action.IAction, org.eclipse.jface.viewers.ISelection)
	 */	
	
	public void selectionChanged(IAction action, ISelection selection) {
		mySelectedElement = null;
		if (selection instanceof IStructuredSelection) {
			IStructuredSelection structuredSelection = (IStructuredSelection) selection;
			if (structuredSelection.size() == 1
					&& structuredSelection.getFirstElement() instanceof WorkflowTypeEditPart) {
				mySelectedElement = (WorkflowTypeEditPart) structuredSelection
						.getFirstElement();
			}
		}
		action.setEnabled(isEnabled());
	}

	
	private boolean isEnabled() {
		return mySelectedElement != null;
	}
}
